/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package cz.muni.fi.veles.marker;

import com.google.common.collect.Iterables;
import cz.muni.fi.veles.infowindow.AbstractInfoWindow;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import javax.faces.application.ResourceDependencies;
import javax.faces.application.ResourceDependency;
import javax.faces.component.UIComponent;
import javax.faces.component.behavior.ClientBehavior;
import javax.faces.component.behavior.ClientBehaviorContext;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.render.Renderer;

/**
 * RendererBase for {@link AbstractMarker}
 * @author Jan Ferko
 */
@ResourceDependencies({
    @ResourceDependency(name="marker.js", target="head")
})
public class MarkerRendererBase extends Renderer{

    /**
     * 
     * @param component component which is being rendered
     * @return key of map server
     */
    public String getMapServerType(UIComponent component){
        if(component == null || !(component instanceof AbstractMarker)){
            return null;
        }
        final AbstractMarker marker = (AbstractMarker) component;
        return marker.resolveMapServer().getId();
    }  
    
    /**
     * 
     * @param component component which is rendered
     * @param context component context
     * @return cliendId of child info window
     */
    public String getInfoWindowId(UIComponent component, FacesContext context){
        if(component == null || !(component instanceof AbstractMarker)){
            return null;
        }
        final AbstractMarker marker = (AbstractMarker) component;
        for(UIComponent child : marker.getChildren()){
            if(child instanceof AbstractInfoWindow){
                return child.getClientId(context);
            }
        }
        return null;
    }
    
    /**
     * 
     * @param component component which is rendered
     * @param context component context
     * @return true if marker has nested marker
     */
    public boolean hasInfoWindow(UIComponent component, FacesContext context){
        return this.getInfoWindowId(component, context) != null;
    }
    
    //returns event script for marker
    //for future 
    public String getEventScript(FacesContext context, UIComponent component, 
            String eventName) throws IOException {
        if(component == null || !(component instanceof AbstractMarker)){
            return "";
        }
        AbstractMarker marker = (AbstractMarker) component;
        ClientBehaviorContext behaviorContext = ClientBehaviorContext.createClientBehaviorContext(context, component, 
                eventName, component.getClientId(context), null);
        Map<String, List<ClientBehavior>> clientBehaviors = marker.getClientBehaviors();
        if(clientBehaviors.containsKey(eventName)){
            final ClientBehavior behavior = Iterables.getFirst(clientBehaviors.get(eventName), null);
            if(behavior != null){
                return behavior.getScript(behaviorContext);
            }
        }
        return "";
                
    }        

    @Override
    public void decode(FacesContext context, UIComponent component) {
        if(component == null || !(component instanceof AbstractMarker)){
            return;
        }
        AbstractMarker marker = (AbstractMarker) component;
        Map<String, List<ClientBehavior>> behaviors = marker.getClientBehaviors();
        if(behaviors.isEmpty()){
            return;
        }
        ExternalContext externalContext = context.getExternalContext();
        Map<String, String> params = externalContext.getRequestParameterMap();
        String event = params.get("javax.faces.behavior.event");
        
        if(event != null){
            List<ClientBehavior> eventBehaviors = behaviors.get(event);
            
            if(behaviors.size() > 0){
                String source = params.get("javax.faces.source");
                String clientId = marker.getClientId(context);
                if(source != null && source.equals(clientId)){
                    for(ClientBehavior eventBehavior : eventBehaviors){
                        eventBehavior.decode(context, component);
                    }
                }
            }
        }
        
    }
    
    
}
